﻿using UnityEngine;
using System.Collections;

//------------------------------------------------------------
// shaco Framework
// Copyright © 2017-2021 chang.liu All rights reserved.
// Feedback: 449612236@qq.com
//------------------------------------------------------------

namespace shaco
{
    public class CurveMoveBy : CurveMoveTo
    {
        private GameObject _tempMoveTarget = null;
        private Vector3 _relativeEndPosition = Vector3.zero;

        static new public CurveMoveBy Create(Vector3 beginPoint, Vector3 endPoint, float duration, params Vector3[] controlPoints)
        {
            if (controlPoints.Length > 2)
            {
                shaco.Log.Error("CurveMoveBy Create warning: max support 2 control point !");
            }

            CurveMoveBy retValue = new CurveMoveBy();
            retValue._beginPoint = beginPoint;
            retValue._controlPoints = controlPoints;
            retValue._endPoint = endPoint;
            retValue.duration = duration;

            return retValue;
        }

        ~CurveMoveBy()
        {
            if (_tempMoveTarget != null)
            {
                MonoBehaviour.DestroyImmediate(_tempMoveTarget);
                _tempMoveTarget = null;
            }
        }

        public override void RunAction(GameObject target)
        {
            if (null == _tempMoveTarget)
            {
                _tempMoveTarget = new GameObject("TempMoveTarget");
            }

            _isRelativeMove = true;
            base.RunAction(_tempMoveTarget);

            _relativeEndPosition = (useWorldPosition ? target.transform.position : target.transform.localPosition) + (_endPoint - _beginPoint);
            var prevPosition = _beginPoint;

            this.onFrameFunc += (float percent) =>
            {
                if (useWorldPosition)
                {
                    var moveOffsetTmp = this._tempMoveTarget.transform.position - prevPosition;
                    target.transform.position += moveOffsetTmp;
                    prevPosition = this._tempMoveTarget.transform.position;
                }
                else
                {
                    var moveOffsetTmp = this._tempMoveTarget.transform.localPosition - prevPosition;
                    target.transform.localPosition += moveOffsetTmp;
                    prevPosition = this._tempMoveTarget.transform.localPosition;
                }
            };

            this.onCompleteFunc -= OnCompletedCallBack;
            this.onCompleteFunc += OnCompletedCallBack;
        }

        public override ActionBase Clone()
        {
            return CurveMoveBy.Create(_beginPoint, _endPoint, duration, _controlPoints);
        }

        public override ActionBase Reverse(GameObject target)
        {
            var pointReverse = new Vector3[_controlPoints.Length];
            for (int i = 0; i < _controlPoints.Length; ++i)
                pointReverse[_controlPoints.Length - i - 1] = _controlPoints[i];
            return CurveMoveBy.Create(_endPoint, _beginPoint, duration, pointReverse);
        }

        private void OnCompletedCallBack(shaco.ActionBase action)
        {
            if (useWorldPosition)
                target.transform.position = _relativeEndPosition;
            else
                target.transform.localPosition = _relativeEndPosition;

            MonoBehaviour.DestroyImmediate(_tempMoveTarget);
            _tempMoveTarget = null;
        }

        private CurveMoveBy() { }
    }
}